"use strict";

const DbMixin = require("../mixins/db.mixin");
const CronMixin = require("moleculer-cron");

/**
 * @typedef {import('moleculer').ServiceSchema} ServiceSchema Moleculer's Service Schema
 * @typedef {import('moleculer').Context} Context Moleculer's Context
 */

/** @type {ServiceSchema} */
module.exports = {
    name: "dashboard",

    /**
     * Mixins
     */
    mixins: [DbMixin("dashboard_stats"), CronMixin],

    /**
     * Settings
     */
    settings: {
        // Available fields in the responses
        fields: [
            "_id",
            "date",
            "totalArticles",
            "totalCategories",
            "totalTags",
            "totalViews",
            "articlesByCategory",
            "dailyArticleGrowth",
            "dailyCategoryGrowth",
            "dailyTagGrowth",
            "dailyViewGrowth",
            "createdAt",
            "updatedAt"
        ],

        // Validator for the `create` & `insert` actions.
        entityValidator: {
            date: "date",
            totalArticles: "number|integer|min:0",
            totalCategories: "number|integer|min:0",
            totalTags: "number|integer|min:0",
            totalViews: "number|integer|min:0",
            articlesByCategory: "object|optional",
            dailyArticleGrowth: "number|integer|optional",
            dailyCategoryGrowth: "number|integer|optional",
            dailyTagGrowth: "number|integer|optional",
            dailyViewGrowth: "number|integer|optional"
        },

        // Cron jobs configuration
        cronJobs: [
            {
                name: "dailyStatsCollection",
                cronTime: "40 23 * * *", // 每天23点40分执行
                onTick: async function () {
                    this.logger.info("🔥 CRON任务触发 - 开始执行每日统计数据收集");
                    try {
                        await this.collectStats();
                        this.logger.info("✅ CRON任务完成 - 每日统计数据收集完成");
                    } catch (error) {
                        this.logger.error("❌ CRON任务失败 - 每日统计数据收集失败:", error);
                    }
                },
                runOnInit: false, // 服务启动时不立即执行
                timeZone: "Asia/Shanghai" // 设置时区为中国时区
            }
        ]
    },

    /**
     * Dependencies
     */
    dependencies: ["blog", "categories", "tags"],

    /**
     * Actions
     */
    actions: {
        /**
         * 获取仪表盘数据
         */
        getDashboardData: {
            rest: "GET /data",
            cache: false,
            async handler(ctx) {
                try {
                    // 获取最新的统计数据
                    const latestStats = await this.adapter.findOne({}, { sort: { date: -1 } });

                    if (!latestStats) {
                        // 如果没有统计数据，先收集一次
                        await this.collectStats();
                        const newStats = await this.adapter.findOne({}, { sort: { date: -1 } });

                        if (!newStats) {
                            return {
                                code: 500,
                                data: null,
                                message: "无法获取仪表盘数据"
                            };
                        }

                        return this.formatResponse(newStats);
                    }

                    return this.formatResponse(latestStats);
                } catch (error) {
                    this.logger.error("获取仪表盘数据出错:", error);
                    return {
                        code: 500,
                        data: null,
                        message: "服务器内部错误"
                    };
                }
            }
        },

        /**
         * 获取趋势数据
         */
        getTrendData: {
            rest: "GET /trends",
            cache: false,
            params: {
                days: { type: "number", integer: true, positive: true, optional: true, default: 30 }
            },
            async handler(ctx) {
                try {
                    const { days } = ctx.params;
                    const limit = Math.min(days, 30); // 最多30天

                    // 获取最近N天的数据
                    const endDate = new Date();
                    const startDate = new Date();
                    startDate.setDate(startDate.getDate() - limit);

                    const stats = await this.adapter.find({
                        query: {
                            date: {
                                $gte: startDate,
                                $lte: endDate
                            }
                        },
                        sort: { date: 1 }
                    });

                    // 格式化趋势数据
                    const trendData = {
                        dates: [],
                        articles: [],
                        categories: [],
                        tags: [],
                        views: []
                    };

                    stats.forEach(stat => {
                        trendData.dates.push(this.formatDate(stat.date));
                        trendData.articles.push(stat.totalArticles);
                        trendData.categories.push(stat.totalCategories);
                        trendData.tags.push(stat.totalTags);
                        trendData.views.push(stat.totalViews);
                    });

                    return {
                        code: 200,
                        data: trendData,
                        message: "success"
                    };
                } catch (error) {
                    this.logger.error("获取趋势数据出错:", error);
                    return {
                        code: 500,
                        data: null,
                        message: "服务器内部错误"
                    };
                }
            }
        },

        /**
         * 获取分类文章分布
         */
        getCategoryDistribution: {
            rest: "GET /category-distribution",
            cache: false,
            async handler(ctx) {
                try {
                    // 获取最新的统计数据
                    const latestStats = await this.adapter.findOne({}, { sort: { date: -1 } });

                    if (!latestStats || !latestStats.articlesByCategory) {
                        // 如果没有统计数据，先收集一次
                        await this.collectStats();
                        const newStats = await this.adapter.findOne({}, { sort: { date: -1 } });

                        if (!newStats || !newStats.articlesByCategory) {
                            return {
                                code: 500,
                                data: null,
                                message: "无法获取分类分布数据"
                            };
                        }

                        return {
                            code: 200,
                            data: newStats.articlesByCategory,
                            message: "success"
                        };
                    }

                    return {
                        code: 200,
                        data: latestStats.articlesByCategory,
                        message: "success"
                    };
                } catch (error) {
                    this.logger.error("获取分类分布数据出错:", error);
                    return {
                        code: 500,
                        data: null,
                        message: "服务器内部错误"
                    };
                }
            }
        },

        /**
         * 手动触发统计数据收集
         */
        collectStatsManually: {
            rest: "POST /collect",
            cache: false,
            async handler(ctx) {
                try {
                    await this.collectStats();
                    return {
                        code: 200,
                        data: null,
                        message: "统计数据收集成功"
                    };
                } catch (error) {
                    this.logger.error("手动收集统计数据出错:", error);
                    return {
                        code: 500,
                        data: null,
                        message: "服务器内部错误"
                    };
                }
            }
        }
    },

    /**
     * Events
     */
    events: {
        // 监听文章创建事件
        "blog.created"() {
            this.updateDailyGrowth("article");
        },

        // 监听分类创建事件
        "categories.created"() {
            this.updateDailyGrowth("category");
        },

        // 监听标签创建事件
        "tags.created"() {
            this.updateDailyGrowth("tag");
        },

        // 监听文章浏览事件
        "blog.viewed"() {
            this.updateDailyGrowth("view");
        }
    },

    /**
     * Methods
     */
    methods: {
        /**
         * 格式化响应数据
         */
        formatResponse(stats) {
            return {
                code: 200,
                data: {
                    totalArticles: stats.totalArticles || 0,
                    totalCategories: stats.totalCategories || 0,
                    totalTags: stats.totalTags || 0,
                    totalViews: stats.totalViews || 0,
                    articlesByCategory: stats.articlesByCategory || {},
                    dailyGrowth: {
                        articles: stats.dailyArticleGrowth || 0,
                        categories: stats.dailyCategoryGrowth || 0,
                        tags: stats.dailyTagGrowth || 0,
                        views: stats.dailyViewGrowth || 0
                    },
                    lastUpdated: stats.updatedAt ? stats.updatedAt.toLocaleString('zh-CN') : new Date().toLocaleString('zh-CN')
                },
                message: "success"
            };
        },

        /**
         * 格式化日期为 YYYY-MM-DD
         */
        formatDate(date) {
            const d = new Date(date);
            const year = d.getFullYear();
            const month = String(d.getMonth() + 1).padStart(2, '0');
            const day = String(d.getDate()).padStart(2, '0');
            return `${year}-${month}-${day}`;
        },

        /**
         * 更新每日增长数据
         */
        async updateDailyGrowth(type) {
            try {
                const today = new Date();
                today.setHours(0, 0, 0, 0);

                // 查找今天的统计数据
                let todayStats = await this.adapter.findOne({
                    query: {
                        date: {
                            $gte: today,
                            $lt: new Date(today.getTime() + 24 * 60 * 60 * 1000)
                        }
                    }
                });

                if (!todayStats) {
                    // 如果今天还没有统计数据，先收集一次
                    await this.collectStats();
                    todayStats = await this.adapter.findOne({
                        query: {
                            date: {
                                $gte: today,
                                $lt: new Date(today.getTime() + 24 * 60 * 60 * 1000)
                            }
                        }
                    });

                    if (!todayStats) {
                        this.logger.error("无法更新每日增长数据：找不到今天的统计数据");
                        return;
                    }
                }

                // 更新对应类型的增长数据
                const updateData = {};

                switch (type) {
                    case "article":
                        updateData.dailyArticleGrowth = (todayStats.dailyArticleGrowth || 0) + 1;
                        updateData.totalArticles = (todayStats.totalArticles || 0) + 1;
                        break;
                    case "category":
                        updateData.dailyCategoryGrowth = (todayStats.dailyCategoryGrowth || 0) + 1;
                        updateData.totalCategories = (todayStats.totalCategories || 0) + 1;
                        break;
                    case "tag":
                        updateData.dailyTagGrowth = (todayStats.dailyTagGrowth || 0) + 1;
                        updateData.totalTags = (todayStats.totalTags || 0) + 1;
                        break;
                    case "view":
                        updateData.dailyViewGrowth = (todayStats.dailyViewGrowth || 0) + 1;
                        updateData.totalViews = (todayStats.totalViews || 0) + 1;
                        break;
                }

                updateData.updatedAt = new Date();

                // 更新数据库
                await this.adapter.updateById(todayStats._id, { $set: updateData });

            } catch (error) {
                this.logger.error(`更新${type}每日增长数据出错:`, error);
            }
        },

        /**
         * 收集统计数据
         */
        async collectStats() {
            try {
                // 获取文章总数
                const articles = await this.broker.call("blog.find", { limit: 0 }, { meta: { $cache: false } });
                const totalArticles = articles.total || 0;

                // 获取分类总数和分类文章分布
                const categories = await this.broker.call("categories.getAdminCategories", {}, { meta: { $cache: false } });
                const totalCategories = categories.data ? categories.data.length : 0;

                // 构建分类文章分布
                const articlesByCategory = {};
                if (categories.data && categories.data.length > 0) {
                    categories.data.forEach(category => {
                        articlesByCategory[category.name] = category.count || 0;
                    });
                }

                // 获取标签总数
                const tags = await this.broker.call("tags.getAdminTags", {}, { meta: { $cache: false } });
                const totalTags = tags.data ? tags.data.length : 0;

                // 获取总浏览量（从文章中累加）
                let totalViews = 0;
                if (articles.rows && articles.rows.length > 0) {
                    articles.rows.forEach(article => {
                        totalViews += article.views || 0;
                    });
                }

                // 获取今天的日期（去除时间部分）
                const today = new Date();
                today.setHours(0, 0, 0, 0);

                // 查找今天是否已有统计数据
                const existingStats = await this.adapter.findOne({
                    date: {
                        $gte: today,
                        $lt: new Date(today.getTime() + 24 * 60 * 60 * 1000)
                    }
                });

                if (existingStats) {
                    // 如果今天已有统计数据，更新它
                    await this.adapter.updateById(existingStats._id, {
                        $set: {
                            totalArticles,
                            totalCategories,
                            totalTags,
                            totalViews,
                            articlesByCategory,
                            updatedAt: new Date()
                        }
                    });
                } else {
                    // 如果今天还没有统计数据，创建新的
                    await this.adapter.insert({
                        date: today,
                        totalArticles,
                        totalCategories,
                        totalTags,
                        totalViews,
                        articlesByCategory,
                        dailyArticleGrowth: 0,
                        dailyCategoryGrowth: 0,
                        dailyTagGrowth: 0,
                        dailyViewGrowth: 0,
                        createdAt: new Date(),
                        updatedAt: new Date()
                    });
                }

                this.logger.info("统计数据收集完成");

            } catch (error) {
                this.logger.error("收集统计数据出错:", error);
                throw error;
            }
        }
    },

    /**
     * Cron jobs
     */


    /**
     * Service created lifecycle event handler
     */
    created() {
        // moleculer-cron will handle the scheduled tasks
    },

    /**
     * Service started lifecycle event handler
     */
    async started() {
        // 服务启动时收集一次统计数据
        try {
            await this.collectStats();
        } catch (error) {
            this.logger.error("初始统计数据收集失败:", error);
        }


    },

    /**
     * Service stopped lifecycle event handler
     */
    stopped() {
        // moleculer-cron will handle cleanup automatically
    }
};